import dayjs from "dayjs";
import { randomString } from "../utils/fun.ts";
import { useConfig } from "./D8dConfigProvider.tsx";
import { useApiRequest } from "./useApiRequest.ts";
import { uploadOSSWithPolicy, uploadMinIOWithPolicy } from "@d8d-appcontainer/api";
import type { 
  OSSUploadPolicy,
  MinioUploadPolicy,
  UploadProgressEvent,
  ProgressCallbacks
} from '@d8d-appcontainer/types';

export interface UploadProps {
  file: Blob;
  filename?: string;
  directory?: string; // 自定义目录参数
  onProgress?: (event: { percent: number }) => void;
  onSuccess?: (filePath: string) => void; // 文件上传成功后的路径
  onError?: (error: any) => void;
}

export default () => {
  const { apiUrl, appConfig } = useConfig();
  const { requestWithToken } = useApiRequest();

  // 获取 OSS 上传策略
  async function getOssPolicy(): Promise<OSSUploadPolicy> {
    if (!apiUrl.aliossToken) throw new Error("未配置 OSS 上传策略接口");
    const res = await requestWithToken({
      url: apiUrl.aliossToken,
      method: "GET",
      data: {},
    });
    if (res.code !== 200 && !res?.success) throw new Error(res.message);
    return res.data;
  }

  // 获取 MinIO 上传策略
  async function getMinioPolicy(): Promise<MinioUploadPolicy> {
    if (!apiUrl.minioToken) throw new Error("未配置 MinIO 上传策略接口");
    const res = await requestWithToken({
      url: apiUrl.minioToken,
      method: "GET",
      data: {},
    });
    if (res.code !== 200 && !res?.success) throw new Error(res.message);
    return res.data;
  }

  // OSS 上传实现
  async function uploadOss(props: UploadProps) {
    const { file, filename, directory, onProgress, onSuccess, onError } = props;
    try {
      const policy = await getOssPolicy();
      
      // 处理文件名和目录
      const finalFilename = filename || `${dayjs().unix()}${randomString(10)}.${file.type.split("/")[1]}`;
      const baseDir = directory || "files/admin_upload";
      const finalDirectory = policy.prefix ? `${policy.prefix}/${baseDir}` : baseDir;
      const finalFilePath = `${finalDirectory}/${finalFilename}`;

      // 设置回调
      const callbacks: ProgressCallbacks<UploadProgressEvent> = {
        onProgress: (event: UploadProgressEvent) => {
          if (onProgress) {
            onProgress({ percent: event.progress });
          }
        },
        onComplete: () => {
          if (onSuccess) {
            onSuccess(finalFilePath);
          }
        },
        onError: (error: Error) => {
          if (onError) {
            onError(error);
          }
        }
      };

      // 执行上传
      await uploadOSSWithPolicy(policy, file, finalFilename, callbacks);

    } catch (error) {
      if (onError) {
        onError(error);
      }
    }
  }

  // MinIO 上传实现
  async function uploadMinio(props: UploadProps) {
    const { file, filename, directory, onProgress, onSuccess, onError } = props;
    try {
      const policy = await getMinioPolicy();
      
      // 处理文件名和目录
      const finalFilename = filename || `${dayjs().unix()}${randomString(10)}.${file.type.split("/")[1]}`;
      const baseDir = directory || "files/admin_upload";
      const finalDirectory = policy.prefix || baseDir;
      const finalFilePath = `${finalDirectory}/${finalFilename}`;

      // 设置回调
      const callbacks: ProgressCallbacks<UploadProgressEvent> = {
        onProgress: (event: UploadProgressEvent) => {
          if (onProgress) {
            onProgress({ percent: event.progress });
          }
        },
        onComplete: () => {
          if (onSuccess) {
            onSuccess(finalFilePath);
          }
        },
        onError: (error: Error) => {
          if (onError) {
            onError(error);
          }
        }
      };

      // 执行上传
      await uploadMinIOWithPolicy(policy, file, finalFilename, callbacks);

    } catch (error) {
      if (onError) {
        onError(error);
      }
    }
  }

  // 统一的上传入口
  async function upload(props: UploadProps) {
    const { storageType } = appConfig;
    if (storageType === "minio") {
      return uploadMinio(props);
    } else {
      return uploadOss(props);
    }
  }

  return {
    upload,
  };
};
